package com.ruoyi.web.controller.core.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ruoyi.comm.crud.bean.dto.CheckUserDTO;
import com.ruoyi.comm.crud.bean.dto.InsertUserDTO;
import com.ruoyi.comm.crud.bean.dto.UpdateUserDTO;
import com.ruoyi.comm.crud.service.IBaseBQService;
import com.ruoyi.common.core.controller.PrefixController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageQO;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.ClzUtils;
import com.ruoyi.common.utils.bean.BeanCopier;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.interceptor.anno.MyPermissions;
import com.ruoyi.web.controller.core.IBaseBQCtroller;

/**
 * BaseBQControllerImpls
 * 
 * @author riverbo
 * @date 2024-05-06
 */
public class BaseBQCtrollerExImpls<M extends IBaseBQService<T, B, Q>, T, B, Q, V> extends PrefixController implements IBaseBQCtroller<T, B, Q, V> {

//    protected final Class<?>[] typeArguments = GenericTypeUtils.resolveTypeArguments(getClass(), ServiceImpl.class);
	
	protected final Class<T> entityClass = currentModelClass();
	
	protected final Class<B> boClass = currentBoClass();
	
	protected final Class<Q> qoClass = currentQoClass();
	
	protected final Class<V> dtoClass = currentDtoClass();

	@Autowired
	protected M baseService;
	
	public InsertUserDTO getInsertDTO() {
		InsertUserDTO dto = new InsertUserDTO();
		//
		SysUser user = getSysUser();
		dto.setCreateBy(user.getLoginName());
		dto.setCreateUserId(user.getUserId());
		dto.setCreateTime(new Date());
		return dto;
	}

	public UpdateUserDTO getUpdateDTO() {
		UpdateUserDTO dto = new UpdateUserDTO();
		//
		SysUser user = getSysUser();
		dto.setUpdateBy(user.getLoginName());
		dto.setUpdateUserId(user.getUserId());
		dto.setUpdateTime(new Date());
		return dto;
	}

	public CheckUserDTO getCheckDTO() {
		CheckUserDTO dto = new CheckUserDTO();
		//
		SysUser user = getSysUser();
		dto.setCheckBy(user.getLoginName());
		dto.setCheckUserId(user.getUserId());
		dto.setCheckTime(new Date());
		return dto;
	}
	
	public void cloneInsertUser(Object obj) {
		InsertUserDTO dto = getInsertDTO();
		BeanCopier.copyProperties(dto, obj);
	}
	
	public void cloneUpdateUser(Object obj) {
		UpdateUserDTO dto = getUpdateDTO();
		BeanCopier.copyProperties(dto, obj);
	}
	
	public void cloneCheckUser(Object obj) {
		CheckUserDTO dto = getCheckDTO();
		BeanCopier.copyProperties(dto, obj);
	}
	
//	public <A> A cloneCheckUser(Class<A> clazz) {
//		CheckUserDTO dto = getCheckDTO();
//		A a = BeanCopier.copyProperties(dto, clazz);
//		return a;
//	}

	public IBaseBQService<T, B, Q> getBaseService() {
		return baseService;
	}

	public Class<T> getEntityClass() {
		return entityClass;
	}

	@SuppressWarnings("unchecked")
	protected Class<T> currentModelClass() {
		return ClzUtils.getSuperClassGenericType(getClass(), 1);
	}

	@SuppressWarnings("unchecked")
	protected Class<B> currentBoClass() {
		return ClzUtils.getSuperClassGenericType(getClass(), 2);
	}

	@SuppressWarnings("unchecked")
	protected Class<Q> currentQoClass() {
		return ClzUtils.getSuperClassGenericType(getClass(), 3);
	}

	@SuppressWarnings("unchecked")
	protected Class<V> currentDtoClass() {
		return ClzUtils.getSuperClassGenericType(getClass(), 4);
	}

	// @RequiresPermissions("biz:casetype:query")
	@Override
	@MyPermissions("查询")
	@GetMapping({ "", "/", "index", "query" })
	public String query(ModelMap mmap) throws Exception {
		String url = prefix + "/query";
		tryPermitted(url);
		return url;
	}

	@Override
	@MyPermissions("选择")
	@GetMapping({ "choice" })
	public String choice(ModelMap mmap) throws Exception {
		String url = prefix + "/choice";
		tryPermitted(url);
		return url;
	}

	/**
	 * 查询 T t 列表
	 */
	// @RequiresPermissions("biz:casetype:list")
	@Override
	@MyPermissions("查询")
	@PostMapping("/list")
	@ResponseBody
	public TableDataInfo list(Q q) throws Exception {
		String url = this.prefix + "/list";
		tryPermitted(url);
		startPage();
		List<T> list = baseService.selectList(q);
		return getDataTable(list);
	}

	@Override
	@MyPermissions("查询")
	@PostMapping("/query")
	@ResponseBody
	public TableDataInfo query(Q q, PageQO page) throws Exception {
		String url = this.prefix + "/query";
		tryPermitted(url);
		List<B> list = baseService.queryBO(q, page);
		return getDataTable(list);
	}

	/**
	 * 导出 T t 列表
	 */
	//@RequiresPermissions("biz:casetype:export")
	@MyPermissions("导出")
	// @Log(title = "casetype", businessType = BusinessType.EXPORT)
	@Override
	@PostMapping("/export")
	@ResponseBody
	public AjaxResult export(Q q) throws Exception {
		String url = this.prefix + "/export";
		tryPermitted(url);
		List<T> list = baseService.selectList(q);
		ExcelUtil<T> util = new ExcelUtil<T>(entityClass);
		return util.exportExcel(list, "export");
	}

	/**
	 * 新增 T t
	 */
//	@Override
//	@MyPermissions("新增")
//	@Override
//	@GetMapping("/add")
//	public String add() throws Exception {
//		String url = prefix + "/add";
//		tryPermitted(url);
//		return url;
//	}

	/**
	 * 新增 T t
	 */
	@MyPermissions("新增")
	@Override
	@GetMapping("/add")
	public String add(ModelMap mmap) throws Exception {
		String url = prefix + "/add";
		tryPermitted(url);
		return url;
	}

	/**
	 * checkNameUnique
	 */
	@Override
	@PostMapping("/checkNameUnique")
	@ResponseBody
	public Boolean checkNameUnique(T t) throws Exception {
		return baseService.checkNameUnique(t);
	}
	
//	public T checkNameUnique(String name) {
//		return baseService.checkNameUnique(name);
//	}

//	@Override
//	@PostMapping("/checkIdNameUnique")
//	@ResponseBody
//	public Long checkIdNameUnique(T t) {
//		return baseService.checkIdNameUnique(t);
//	}

//	@Override
//	@PostMapping("/existsIdNameUnique")
//	@ResponseBody
//	public Boolean existsIdNameUnique(T t) {
//		return baseService.existsIdNameUnique(t);
//	}

	/**
	 * 新增保存 T t
	 */
	@Override
	// @RequiresPermissions("biz:casetype:add")
	@MyPermissions("新增")
	// @Log(title = "casetype", businessType = BusinessType.INSERT)
	@PostMapping("/add")
	@ResponseBody
	public AjaxResult addSave(@Validated V v) throws Exception {
		String url = prefix + "/add";
		tryPermitted(url);
		cloneInsertUser(v);
		int n = baseService.insertA(v);
		AjaxResult result = toAjax(n);
		return result;
	}
	
	public B selectBOById(Long id) {
		B bo = baseService.selectBOById(id);
		return bo;
	}

	/**
	 * 打开修改页面 id
	 */
	@Override
	@MyPermissions("修改")
	@GetMapping("/edit/{id}")
	public String edit(@PathVariable("id") Long id, ModelMap mmap) throws Exception {
		String url = prefix + "/edit";
		tryPermitted(url);
		B bo = this.selectBOById(id);
		mmap.put("vo", bo);
		return url;
	}

	/**
	 * 修改保存 T t
	 */
	@Override
	@MyPermissions("修改")
	// @RequiresPermissions("biz:casetype:edit")
	// @Log(title = "casetype", businessType = BusinessType.UPDATE)
	@PostMapping("/edit")
	@ResponseBody
	public AjaxResult editSave(@Validated V v) throws Exception {
		String url = prefix + "/edit";
		tryPermitted(url);
		cloneUpdateUser(v);
		int n = baseService.updateA(v);
		return toAjax(n);
	}

	/**
	 * 修改保存 T t
	 */
	@Override
	@MyPermissions("修改")
	// @RequiresPermissions("biz:casetype:edit")
	// @Log(title = "casetype", businessType = BusinessType.UPDATE)
	@PostMapping("/apply")
	@ResponseBody
	public AjaxResult applySave(@Validated V v) throws Exception {
		String url = prefix + "/apply";
		tryPermitted(url);
		cloneUpdateUser(v);
		int n = baseService.applyA(v);
		return toAjax(n);
	}

	/**
	 * 删除 T t
	 */
	@Override
	// @RequiresPermissions("biz:casetype:remove")
	@MyPermissions("删除")
	// @Log(title = "casetype", businessType = BusinessType.DELETE)
	@PostMapping("/remove")
	@ResponseBody
	public AjaxResult remove(String ids) throws Exception {
		String url = prefix + "/remove";
		tryPermitted(url);
		int n = baseService.deleteByIds(ids);
		return toAjax(n);
	}
	
//	@MyPermissions("审批")
//	// @RequiresPermissions("biz:casetype:edit")
//	// @Log(title = "casetype", businessType = BusinessType.UPDATE)
//	@PostMapping("/check")
//	@ResponseBody
//	public AjaxResult check(String ids) throws Exception {
//		String url = prefix + "/check";
//		tryPermitted(url);
//		CheckDataDTO data = BeanCopier.copyProperties(getCheckDTO(), CheckDataDTO.class);
//		data.setIds(Convert.toLongArray(ids));
//		int n = baseService.checkByIds(data);
//		return toAjax(n);
//	}
	
	/**
	 * 查看修改页面 id
	 */
//	@Override
	@MyPermissions("审批")
	@GetMapping("/view/{id}")
	public String view(@PathVariable("id") Long id, ModelMap mmap) throws Exception {
		String url = prefix + "/view";
		tryPermitted(url);
		B b = this.selectBOById(id);
		mmap.put("vo", b);
		return url;
	}
	
	/**
	 * 打开修改页面 id
	 */
//	@Override
	@MyPermissions("审批")
	@GetMapping("/check/{id}")
	public String check(@PathVariable("id") Long id, ModelMap mmap) throws Exception {
		String url = prefix + "/check";
		tryPermitted(url);
		B b = baseService.selectBOById(id);
		mmap.put("vo", b);
		return url;
	}
	
//	@PostMapping("/upload")
//	public String upload(@ModelAttribute UploadFileDTO dto, ModelMap model, @RequestParam("file") MultipartFile file) throws Exception {
//		return "";
//	}

//	@GetMapping("/download/{caseId}/{item}/{filename:.+}")
//	public ResponseEntity<Resource> download(@PathVariable Integer caseId, @PathVariable Integer item, @PathVariable String filename) throws Exception {
//		return null;
//	}

//	  @GetMapping("/delete/{caseId}/{item}/{filename:.+}")
//	  public String delete(@PathVariable Integer caseId, @PathVariable Integer item, @PathVariable String filename, Model model, RedirectAttributes redirectAttributes) {
//	    return "";
//	  }

	@MyPermissions("审批")
	// @RequiresPermissions("biz:casetype:edit")
	// @Log(title = "casetype", businessType = BusinessType.UPDATE)
	@PostMapping("/check")
	@ResponseBody
	public AjaxResult checkSave(@Validated V v) throws Exception {
		String url = prefix + "/check";
		tryPermitted(url);
		cloneCheckUser(v);
		int n = baseService.checkA(v);
		return toAjax(n);
	}

}